home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / uucp / system.c < prev    next >
C/C++ Source or Header  |  1996-07-29  |  10KB  |  384 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "../misc/misc.h"
  5. #include "uucp.h"
  6. #include "internal.h"
  7. #include "../netconf/netconf.h"
  8. #include "../userconf/userconf.h"
  9. #include "uucp.m"
  10.  
  11. UUCP_HELP_FILE help_uucp ("uucp");
  12. static UUCP_HELP_FILE help_system ("system");
  13. static CONFIG_FILE f_systems (VAR_LIB_UUCP_SYSTEMS
  14.     ,help_uucp
  15.     ,CONFIGF_OPTIONNAL|CONFIGF_MANAGED
  16.     ,"uucp","uucp",0660);
  17.  
  18.  
  19. PUBLIC SYSTEM::SYSTEM()
  20. {
  21.     speed = 38400;
  22.     tbchat[0].expected.setfrom ("ogin:");
  23.     tbchat[1].expected.setfrom ("assword:");
  24. }
  25. /*
  26.     Initialise a record from a  line of the Systems file
  27. */
  28. PUBLIC SYSTEM::SYSTEM(const char *line, const SSTRING &_comment, char *err)
  29. {
  30.     err[0] = '\0';
  31.     line = str_copyword (name,line);
  32.     line = str_copyword (when,line);    
  33.     line = str_copyword (acu,line);    
  34.     char word[100];
  35.     line = str_copyword (word,line);    
  36.     speed = atoi (word);
  37.     line = str_copyword (phone,line);
  38.     line = str_skip(line);
  39.     int nbchat = 0;
  40.     while (nbchat < NBCHAT_ELM){
  41.         CHAT_ELM *e = tbchat + nbchat;
  42.         line = str_copyword (word,line);
  43.         if (word[0] == '\0') break;
  44.         if (strcmp(word,"\"\"")==0) word[0] = '\0';
  45.         e->expected.setfrom (word);
  46.         line = str_copyword (word,line);
  47.         if (word[0] == '\0') break;
  48.         if (strcmp(word,"\"\"")==0) word[0] = '\0';
  49.         e->send.setfrom (word);
  50.         nbchat++;
  51.     }
  52.     comment.setfrom (_comment);
  53.     comment.strip_end();
  54. }
  55.  
  56. PUBLIC void SYSTEM::write (FILE *fout)
  57. {
  58.     /* #Specification: uucp / file "Systems" / comments
  59.         Linuxconf is trying to keep the original comments in
  60.         the file.
  61.     */
  62.     comment_write (comment,fout);
  63.     fprintf (fout,"%s %s %s %d %s "
  64.         ,name.get(),when.get(),acu.get()
  65.         ,speed,phone.get());
  66.     for (int i=0; i<NBCHAT_ELM; i++){
  67.         CHAT_ELM *e = tbchat + i;
  68.         if (!e->expected.is_empty()
  69.             || !e->send.is_empty()){
  70.             const char *expec = e->expected.get();
  71.             if (expec[0] == '\0') expec = "\"\"";
  72.             const char *send = e->send.get();
  73.             if (send[0] == '\0') send = "\"\"";
  74.             fprintf (fout,"%s %s ",expec,send);
  75.         }
  76.     }
  77.     fputc ('\n',fout);
  78. }
  79.  
  80. static void check_empty (
  81.     SSTRING fld,
  82.     const char *msg,
  83.     char *err,
  84.     int &nof,
  85.     int field_no)
  86. {
  87.     if (fld.is_empty()){
  88.         strcat (err,msg);
  89.         strcat (err," ");
  90.         strcat (err,MSG_U(E_EMPTY,"must not be empty"));
  91.         if (nof == -1) nof = field_no;
  92.     }
  93. }
  94.  
  95. /*
  96.     Edit one system record.
  97.     Return -1 if the user quit editing.
  98.     Return  0 if the user accept the changes
  99.     Return  1 if the user wish to delete the record.
  100. */
  101. PUBLIC int SYSTEM::edit(
  102.     PERMISSIONS &perms,
  103.     POLLS &polls)
  104. {
  105.     int ret = -1;
  106.     DIALOG dia;
  107.     dia.newf_str (MSG_U(F_UUCPSYS,"Remote system name"),name);
  108.     FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_WHEN,"Schedule"),when);
  109.     comb->addopt ("Any",MSG_U(M_ANY,"Your system call anytime needed"));
  110.     comb->addopt ("Never",MSG_U(M_NEVER,"The other site is calling you"));
  111.     comb->addopt ("8-10,14-16",MSG_U(M_EXAMPLE,"One example"));
  112.     comb = dia.newf_combo (MSG_U(F_TYPE,"Transport type"),acu);
  113.     comb->addopt ("ACU",MSG_U(M_MODEM,"Modem device"));
  114.     comb->addopt ("Direct",MSG_U(M_DIRECT,"Null modem serial line"));
  115.     comb->addopt ("Tcp",MSG_U(M_UUCPTCP,"UUCP over TCP/IP"));
  116.     SSTRING speedstr;
  117.     baud_setfield (speed,speedstr,dia);
  118.     
  119.     dia.newf_str (MSG_U(F_PHONE,"Phone"),phone);
  120.     POLL *poll = polls.getitem(name.get());
  121.     POLL *newpoll = NULL;
  122.     if (poll == NULL){
  123.         newpoll = new POLL (name.get());
  124.         poll = newpoll;
  125.     }
  126.     dia.newf_str (MSG_U(F_SCHED,"Polling schedule"),poll->sched);
  127.     #if 0
  128.         // Comment handling is just too simple to be useful. A full
  129.         // editor is need, not a single line.
  130.         dia.newf_str (MSG_U(F_COMMENT,"Comment"),comment);
  131.     #endif
  132.     dia.newf_title ("",MSG_U(T_LOGINSCRIPT,"Login script"));
  133.     int i;
  134.     for (i=0; i<NBCHAT_ELM; i++){
  135.         CHAT_ELM *e = tbchat + i;
  136.         dia.newf_str (i==0
  137.             ? MSG_U(F_EXPECTEDLOGIN,"Expected login prompt")
  138.             : MSG_U(F_EXPECTED,"Expected")
  139.             ,e->expected);
  140.         dia.newf_str (MSG_U(F_SEND,"Send"),e->send);
  141.     }
  142.     PERMISSIONS ptmp;
  143.     ptmp.neverdelete();
  144.     if (!name.is_empty()){
  145.         int no = 0;
  146.         PERMISSION *p;
  147.         while ((p=perms.getitem(name.get(),no))!=NULL){
  148.             ptmp.add (p);
  149.         }
  150.     }
  151.     int no_perms = ptmp.getnb()==0;    // No permission record defined
  152.     /* #Specification: uucp / permissions / many per site
  153.         Several Permission config are possible for one site.
  154.         They are differentiate with the logname entry.
  155.         Linuxconf support this by always proposing few empty slots
  156.         at the end of the dialog
  157.     */
  158.     const int SPARE_P = 3;
  159.     PERMISSION pnew[SPARE_P];
  160.     for (i=0; i<SPARE_P; i++) ptmp.add (pnew+i);
  161.     int start_perm = dia.getnb();
  162.     int nb_perm = 0;
  163.     for (i=0; i<ptmp.getnb(); i++){
  164.         int tmp = dia.getnb();
  165.         PERMISSION *p = ptmp.getitem(i);
  166.         dia.newf_title ("",MSG_U(T_PERMCONF,"Permission configuration"));
  167.         FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_LOGNAME,"Login name")
  168.             ,p->logname);
  169.         USERS users;
  170.         for (int u=0; u<users.getnb(); u++){
  171.             USER *user = users.getitem(u);
  172.             if (strcmp(user->getshell(),USR_LIB_UUCP_UUCICO)==0){
  173.                 comb->addopt(user->getname(),user->getgecos());
  174.             }
  175.         }
  176.     
  177.         dia.newf_str (MSG_U(F_MASQUERADE,"Masquerade as"),p->myname);
  178.         dia.newf_chk ("",p->mayrequest,MSG_U(F_MAYREQUEST,"May request files"));
  179.         dia.newf_str (MSG_U(F_DIRREAD,"May read"),p->dirread);
  180.         dia.newf_chk ("",p->maysend,MSG_U(F_MAYSEND,"May send files"));
  181.         dia.newf_str (MSG_U(F_MAYWRITE,"May write"),p->dirwrite);
  182.         dia.newf_str (MSG_U(F_MAYEXEC,"Available commands"),p->commands);
  183.         nb_perm = dia.getnb() - tmp;    // How many field per permission record
  184.     }
  185.         
  186.     int nof = 0;
  187.     while (1){
  188.         MENU_STATUS code = dia.edit(MSG_U(T_SYSTEM,"One system configuration")
  189.             ,MSG_U(I_SYSTEM,"You must define how and when one\n"
  190.              "system can be reached.\n")
  191.             ,help_system
  192.             ,nof
  193.             ,MENUBUT_EDIT|MENUBUT_ACCEPT|MENUBUT_CANCEL|MENUBUT_DEL);
  194.         if (code == MENU_EDIT){
  195.             int noperm = (nof - start_perm)/nb_perm;
  196.             if ((nof - start_perm)%nb_perm == 1){
  197.                 // EDIT on a login name field
  198.                 dia.save();
  199.                 PERMISSION *p = ptmp.getitem(noperm);
  200.                     p->machine.setfrom (name);
  201.                 const char *logname = p->logname.get();
  202.                 if (logname[0] != '\0'){
  203.                     users_editone (logname,UUCP_GROUP);
  204.                 }else{
  205.                     xconf_error (MSG_U(E_EMPTYLOGNAME,"No login name"));
  206.                 }
  207.             }else{
  208.                 xconf_error (MSG_U(E_NOEDIT,"No edit on this field"));
  209.             }
  210.         }else if (code == MENU_CANCEL || code == MENU_ESCAPE){
  211.             break;
  212.         }else if (code == MENU_DEL){
  213.             if (xconf_areyousure(MSG_U(Q_DELSYSTEM
  214.                 ,"Confirm deletion of uucp system"))){
  215.                 ret = 1;
  216.                 break;
  217.             }
  218.         }else{
  219.             char err[2000];
  220.             err[0] = '\0';
  221.             nof = -1;
  222.             // nof will be positionned on the first field with an error
  223.             check_empty (name,MSG_U(E_NAME,"Site name"),err,nof,0);
  224.             check_empty (when,MSG_U(E_SCHED,"Schedule"),err,nof,1);
  225.             check_empty (speedstr,MSG_U(E_SPEED,"modem speed"),err,nof,2);
  226.             check_empty (phone,MSG_U(E_PHONE,"Phone"),err,nof,3);
  227.             if (err[0] != '\0'){
  228.                 xconf_error (MSG_U(E_SOMERRORS,"There are some errors\n\%s")
  229.                     ,err);
  230.             }else{
  231.                 /* #Specification: uucp / permission record / at least one
  232.                     There is at least one permission record for each uucp
  233.                     site. Subsequent permission configs will be collected
  234.                     when the LOGNAME field is non empty.
  235.                 */
  236.                 for (i=0; i<ptmp.getnb(); i++){
  237.                     PERMISSION *p = ptmp.getitem(i);
  238.                     p->machine.setfrom (name);
  239.                     const char *logname = p->logname.get();
  240.                     if (logname[0] != '\0'){
  241.                         if (!user_exist (logname)){
  242.                             users_editone (logname,UUCP_GROUP);
  243.                         }
  244.                     }else if (logname[0] == '\0' && i > 0){
  245.                         perms.remove_del (p);
  246.                         ptmp.remove (p);
  247.                         i--;
  248.                     }
  249.                 }
  250.                 for (i=0; i<SPARE_P; i++){
  251.                     PERMISSION *p = pnew+i;
  252.                     if (!p->logname.is_empty()
  253.                         || (i== 0 && no_perms)){
  254.                         perms.add (new PERMISSION (p));
  255.                     }
  256.                 }
  257.                 speed = speedstr.getval();
  258.                 if (poll->sched.is_empty()){
  259.                     polls.remove_del (poll);
  260.                     delete newpoll;
  261.                 }else if (newpoll != NULL){
  262.                     polls.add (newpoll);
  263.                 }
  264.                 ret = 0;
  265.                 break;
  266.             }
  267.         }
  268.     }
  269.     if (ret != 0) dia.restore();
  270.     return ret;
  271. }
  272.  
  273.  
  274. PUBLIC SYSTEM *SYSTEMS::getitem(int no)
  275. {
  276.     return (SYSTEM*)ARRAY::getitem(no);
  277. }
  278.  
  279.  
  280. PROTECTED CONFIG_OBJ *SYSTEMS::newobj (
  281.     const char *buf,    // Buffer to parse from the Permissions file
  282.     const SSTRING &_comments,    // Comments preceding the definition
  283.     char *err)            // Will contain error message or '\0'
  284. {
  285.     return new SYSTEM (buf,_comments,err);
  286. }
  287.  
  288.  
  289. PUBLIC SYSTEMS::SYSTEMS()
  290.     : CONFIG_OBJS (f_systems)
  291. {
  292.     read();
  293. }
  294.  
  295. static int cmp_by_name (const ARRAY_OBJ *o1, const ARRAY_OBJ *o2)
  296. {
  297.     SYSTEM *s1 = (SYSTEM*)o1;
  298.     SYSTEM *s2 = (SYSTEM*)o2;
  299.     return s1->name.cmp(s2->name);
  300. }
  301.  
  302. PUBLIC void SYSTEMS::sort()
  303. {
  304.     ARRAY::sort (cmp_by_name);
  305. }
  306.  
  307. /*
  308.     Edit the different systems.
  309.     Return -1 if the user escape
  310. */
  311. PUBLIC int SYSTEMS::edit(
  312.     PERMISSIONS &perms,
  313.     POLLS &polls)
  314. {
  315.     int ret = 0;
  316.     int sel = 0;
  317.     while (1){
  318.         DIALOG dia;
  319.         int n = getnb();
  320.         sort();
  321.         for (int i=0; i<n; i++){
  322.             SYSTEM *s = getitem(i);
  323.             dia.new_menuitem ("",s->name);
  324.         }
  325.         dia.addwhat (MSG_U(I_ADDSYS,"to add one new configuration"));
  326.         MENU_STATUS code = dia.editmenu (
  327.             MSG_U(T_SYSTEMS,"Edit uucp configurations")
  328.             ,MSG_U(I_SYSTEMS,"Each configuration control the way\n"
  329.              "your computer interact with other computers using\n"
  330.              "the UUCP protocol (background file transfer)\n")
  331.             ,help_uucp
  332.             ,sel,0);
  333.         if (code == MENU_OK){
  334.             if (n > 0){
  335.                 SYSTEM *s = getitem(sel);
  336.                 s->edit(perms,polls);
  337.             }
  338.         }else if (code == MENU_ESCAPE
  339.             || code == MENU_QUIT){
  340.             if (!was_modified()
  341.                 || xconf_quitwosave()){
  342.                 break;
  343.             }
  344.         }else if (code == MENU_SAVE){
  345.             ret = 0;
  346.             break;
  347.         }else if (code == MENU_ADD){
  348.             SYSTEM *s = new SYSTEM;
  349.             if (s->edit(perms,polls)!=-1){
  350.                 add (s);
  351.             }else{
  352.                 delete s;
  353.             }
  354.         }else if (code == MENU_DEL){
  355.             if (n > 0){
  356.                 SYSTEM *s = getitem(sel);
  357.                 PERMISSION *p;
  358.                 while ((p=perms.getitem(s->name.get()))!=NULL){
  359.                     perms.remove_del (p);
  360.                 }
  361.                 remove_del (s);
  362.             }
  363.         }
  364.     }
  365.     return ret;
  366. }
  367.  
  368. void system_edit ()
  369. {
  370.     if (perm_rootaccess (MSG_U(P_UUCP,"to manage uucp"))){
  371.         SYSTEMS systems;
  372.         PERMISSIONS perms;
  373.         POLLS polls;
  374.         polls.read ();
  375.         perms.read ();
  376.         if (systems.edit(perms,polls)==0){
  377.             perms.write();
  378.             polls.write();
  379.             systems.write();
  380.         }
  381.     }
  382. }
  383.  
  384.